<?php
/**
 * 支付宝当面付SDK
 */
class AlipayF2F {
    private $appId;
    private $privateKey;
    private $publicKey;
    private $notifyUrl;
    private $returnUrl;
    
    public function __construct($appId, $privateKey, $publicKey, $notifyUrl, $returnUrl) {
        $this->appId = $appId;
        $this->privateKey = $privateKey;
        $this->publicKey = $publicKey;
        $this->notifyUrl = $notifyUrl;
        $this->returnUrl = $returnUrl;
    }
    
    /**
     * 生成当面付二维码
     */
    public function createQRCode($orderNo, $amount, $subject) {
        $params = [
            'app_id' => $this->appId,
            'method' => 'alipay.trade.precreate',
            'format' => 'JSON',
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'notify_url' => $this->notifyUrl,
            'biz_content' => json_encode([
                'out_trade_no' => $orderNo,
                'total_amount' => $amount,
                'subject' => $subject,
                'timeout_express' => '2h'
            ])
        ];
        
        $params['sign'] = $this->generateSign($params);
        
        $url = 'https://openapi.alipay.com/gateway.do?' . http_build_query($params);
        
        // 发送请求
        $response = $this->sendRequest($url);
        $result = json_decode($response, true);
        
        if (isset($result['alipay_trade_precreate_response']['qr_code'])) {
            return $result['alipay_trade_precreate_response']['qr_code'];
        }
        
        return false;
    }
    
    /**
     * 查询订单状态
     */
    public function queryOrder($orderNo) {
        $params = [
            'app_id' => $this->appId,
            'method' => 'alipay.trade.query',
            'format' => 'JSON',
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'biz_content' => json_encode([
                'out_trade_no' => $orderNo
            ])
        ];
        
        $params['sign'] = $this->generateSign($params);
        
        $url = 'https://openapi.alipay.com/gateway.do?' . http_build_query($params);
        
        $response = $this->sendRequest($url);
        $result = json_decode($response, true);
        
        if (isset($result['alipay_trade_query_response'])) {
            return $result['alipay_trade_query_response'];
        }
        
        return false;
    }
    
    /**
     * 验证异步通知
     */
    public function verifyNotify($data) {
        $sign = $data['sign'];
        unset($data['sign'], $data['sign_type']);
        
        $string = $this->buildQueryString($data);
        $publicKey = $this->publicKey;
        if (strpos($publicKey, '-----') === false) {
            $publicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->publicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
        }
        
        return openssl_verify($string, base64_decode($sign), $publicKey, OPENSSL_ALGO_SHA256) === 1;
    }
    
    /**
     * 生成签名
     */
    private function generateSign($params) {
        $string = $this->buildQueryString($params);
        
        $privateKey = $this->privateKey;
        if (strpos($privateKey, '-----') === false) {
            $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->privateKey, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
        }
        
        $sign = '';
        openssl_sign($string, $sign, $privateKey, OPENSSL_ALGO_SHA256);
        
        return base64_encode($sign);
    }
    
    /**
     * 构建查询字符串
     */
    private function buildQueryString($params) {
        ksort($params);
        $string = '';
        foreach ($params as $key => $value) {
            if ($value !== '' && $value !== null) {
                $string .= $key . '=' . $value . '&';
            }
        }
        return rtrim($string, '&');
    }
    
    /**
     * 发送HTTP请求
     */
    private function sendRequest($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
}
?> 